/*
 * Node.cpp
 *
 *  Created on: 14.04.2010
 *      Author: king
 */

#include <QtGui>

#include "Link.h"
#include "Node.h"

namespace etu {
namespace ui {

static QColor DEAD = Qt::black;
static QColor LIVE = Qt::darkGreen;

CNode::CNode(Person* person)
{
    m_outlineColor = Qt::darkBlue;
    m_backgroundColor = Qt::white;
    m_text = tr((person->getFirstName()).c_str()) + "\n" + tr(person->getLastName().c_str());

    setFlags(ItemIsMovable | ItemIsSelectable);

    m_pixmap = new QPixmap();
    setPerson(person);
}

CNode::~CNode()
{
  foreach (CLink *link, m_links)
    delete link;

  delete m_pixmap;
}

void CNode::setPerson(Person* person)
{
    prepareGeometryChange();
    m_person = person;
    update();
}

void CNode::setupPersonName()
{
  m_text = tr((m_person->getFirstName()).c_str()) + "\n" + tr(m_person->getLastName().c_str());
}

Person* CNode::getPerson()
{
  return m_person;
}

QString CNode::text() const
{
    return m_text;
}

void CNode::setTextColor(const QColor &color)
{
    m_textColor = color;
    update();
}

QColor CNode::textColor() const
{
    return m_textColor;
}

void CNode::setOutlineColor(const QColor &color)
{
    m_outlineColor = color;
    update();
}

QColor CNode::outlineColor() const
{
    return m_outlineColor;
}

void CNode::setBackgroundColor(const QColor &color)
{
    m_backgroundColor = color;
    update();
}

QColor CNode::backgroundColor() const
{
    return m_backgroundColor;
}

void CNode::addLink(CLink *link)
{
    m_links.insert(link);
}

void CNode::removeLink(CLink *link)
{
    m_links.remove(link);
}

QRectF CNode::boundingRect() const
{
    const int Margin = 1;
    return outlineRect().adjusted(-Margin, -Margin, +Margin, +Margin);
}

QPainterPath CNode::shape() const
{
    QRectF rect = outlineRect();

    QPainterPath path;
    path.addRoundRect(rect, roundness(rect.width()),
                      roundness(rect.height()));
    return path;
}

void CNode::paint(QPainter *painter,
                 const QStyleOptionGraphicsItem *option,
                 QWidget * /* widget */)
{
  	m_textColor = m_person->isDead() ? DEAD : LIVE;
	QPen pen(m_outlineColor);

    if (option->state & QStyle::State_Selected) {
        pen.setStyle(Qt::DotLine);
        pen.setWidth(2);
    }
    painter->setPen(pen);
    painter->setBrush(m_backgroundColor);

    QRectF rect = outlineRect();
    QRectF textRect = rect;

    painter->drawRoundRect(rect, roundness(rect.width()),
                           roundness(rect.height()));

    painter->setPen(m_textColor);
    if (!m_scaledPixmap.isNull())
    {
      QRectF source = QRectF(1,-1,m_scaledPixmap.width()+1,m_scaledPixmap.height()*2);
      painter->drawPixmap(rect,m_scaledPixmap,source);
      textRect = outlineTextRect();
    }

    painter->drawText(textRect, Qt::AlignCenter, m_text);
}

void CNode::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
{

}

QVariant CNode::itemChange(GraphicsItemChange change,
                          const QVariant &value)
{
    if (change == ItemPositionHasChanged) {
        foreach (CLink *link, m_links)
            link->trackNodes();
        //trackNodes();
    }
    return QGraphicsItem::itemChange(change, value);
    update();//?
}

void CNode::trackNodes()
{
   foreach (CLink *link, m_links)
      link->trackNodes();

   foreach (QGraphicsItem* node, this->childItems())
     dynamic_cast<CNode *>(node)->trackNodes();
}

QRectF CNode::outlineRect() const
{
    const int Padding = 8;
    QFontMetricsF metrics = qApp->font();
    QRect re = m_scaledPixmap.rect();
    QRectF rect = metrics.boundingRect(QRect(),Qt::TextWordWrap,m_text);
    double widthPadding = (re.width()-rect.width() > 0) ? re.width()-rect.width() : 0;
    double heightPadding = (re.height()*2-rect.height() > 0) ? re.height()*2-rect.height() : 0;
    rect.adjust(-Padding, -Padding, widthPadding+Padding, heightPadding+Padding);
    rect.translate(-rect.center());
    return rect;
}

QRectF CNode::outlineTextRect() const
{
    const int Padding = 8;
    QFontMetricsF metrics = qApp->font();
    QRectF rect = metrics.boundingRect(QRect(),Qt::TextWordWrap,m_text);
    rect.adjust(-Padding, -Padding, Padding, +Padding);
    rect.translate(-rect.center().x(),-rect.topLeft().y());
    return rect;
}

int CNode::roundness(double size) const
{
    const int Diameter = 12;
    return 100 * Diameter / int(size);
}

void CNode::setPhoto(QPixmap* pixmap)
{
  m_scaledPixmap = pixmap->scaledToHeight(50,Qt::SmoothTransformation);
  m_pixmap = pixmap;
  update();
}

QPixmap* CNode::getPhoto()
{
  return m_pixmap;
}

}
}
